﻿// This software is the confidential and proprietary information of NetBay.
// Such confidential information should not be disclosed.
// NetBay copyright(c) 2012

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using NetBay.Core.BusinessEntities;
using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Framework.Pages;
using Rio.Framework.Pages.AppCode.Enums;
using Rio.Framework.Pages.Context;
using Rio.Framework.Pages.Controls;
using Rio.Framework.Pages.Enums;
using Rio.Framework.Pages.Events;
using Rio.Framework.Pages.Helpers;
using Rio.Framework.Pages.Helpers.Utils;
using Rio.Framework.Pages.Manager;
using Rio.Search.Application.Controls;
using Telerik.Windows.Controls;

namespace Rio.Application.RioWeb.Search.Views
{
    public partial class SearchView : INotifyPropertyChanged
    {
        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Fields

        private SearchHomeTab _searchHomeTab;
        private int _foldersCount = 1;
        private ControlBase _selectedTab;
        private ObservableCollection<ControlBase> _tabs = new ObservableCollection<ControlBase>();

        #endregion

        #region Properties

        public bool IsDirty { get; set; }

        public ObservableCollection<ControlBase> Tabs
        {
            get { return _tabs; }
            set
            {
                _tabs = value;
                OnPropertyChanged("Tabs");
            }
        }

        public ControlBase SelectedTab
        {
            get { return _selectedTab; }
            set
            {
                _selectedTab = value;
                OnPropertyChanged("SelectedTab");

                TabSelectionChanged();
            }
        }

        public List<FolderPage> FolderPages
        {
            get
            {
                return (from tab in Tabs
                        where tab is FolderPage
                        select tab as FolderPage).ToList();
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        ///   Initializes a new instance of the <see cref = "SearchPage" /> class.
        /// </summary>
        public SearchView()
        {
            InitializeComponent();

            WorkflowManager.Activate();

            if (HtmlPage.Document.DocumentUri.OriginalString.Contains("?"))
                QueryByUriManager.Init(HtmlPage.Document.DocumentUri, QueryByUriType.Search);

            if (LoginManager.Instance.CurrentUser != null)
                Initialization();
            else
            {
                //if (LoginManager.Instance.AuthenticationMethod == LoginDomainServiceEnums.AuthenticationMethod.SSO)
                //{
                    LoginManager.Instance.AuthenticatedUser += (sender, args) => Initialization();
                //}
            }
        }

        #endregion

        public void Initialization()
        {
            headMenu.LoadUser(ApplicationName.RioSearch);

            if (QueryByUriManager.SearchInstance == null || QueryByUriManager.SearchInstance.SearchAction != QueryByUriSearchAction.SingleConsultation)
            {
                _searchHomeTab = new SearchHomeTab
                                     {
                                         FolderPages = FolderPages
                                     };

                _searchHomeTab.SearchResultClicked += SearchHomeTabSearchResultClicked;
                _searchHomeTab.DocumentPasted += SearchHomeTabDocumentPasted;

                Tabs.Add(_searchHomeTab);
                SelectedTab = _searchHomeTab;
            }

            busyIndicator.Visibility = Visibility.Collapsed;

            //A search by uri is performed
            if (QueryByUriManager.SearchInstance != null)
            {
                switch (QueryByUriManager.SearchInstance.SearchAction)
                {
                    case QueryByUriSearchAction.Consultation:
                    case QueryByUriSearchAction.SingleConsultation:
                        PerformConsultationByUri();
                        break;
                    default:
                        _searchHomeTab.searchPanel.PerformSearchByUri();
                        break;
                }
            }
        }

        private void SearchHomeTabDocumentPasted(long folderId)
        {
            FolderPages.Where(f => f.CurrentFolder.Identifier == folderId).ToList().ForEach(
                f => f.LoadFolderDocument());
        }

        private void SearchHomeTabSearchResultClicked(Folder folder, Document document)
        {
            try
            {
                if (Tabs.Count == 11)
                {
                    MessageBoxChildWindow message = new MessageBoxChildWindow(
                        String.Empty,
                        Resx.GetLabel(ResxSearchPage.MSG_NB_MAX_TAB),
                        MessageBoxButtons.Ok,
                        MessageBoxIcon.Warning);

                    message.ShowDialog();
                }
                else
                {
                    FolderPage folderPageAlreadyOpen = null;

                    if (folder != null)
                    {
                        //Check if the folder is not already open
                        folderPageAlreadyOpen =
                            FolderPages.Where(f => f.CurrentFolder.Identifier == folder.Identifier).FirstOrDefault();

                        if (folderPageAlreadyOpen == null)
                        {
                            SplashScreenManager.Wait(this);

                            BusinessEntitiesDomainContext businessEntitiesDomainContext =
                                GlobalWebContext.BusinessEntitiesDomainContext;
                            var query =
                                businessEntitiesDomainContext.GetFolderQuery(_searchHomeTab.Organization.Identifier,
                                                                             _searchHomeTab.FolderType.Identifier,
                                                                             folder.Identifier,
                                                                             folder.Iddoc,
                                                                             folder.FullTextDocList);
                            businessEntitiesDomainContext.Load(
                                query,
                                result =>
                                {
                                    if (!result.HasError && result.Entities != null
                                        && result.Entities.Count() > 0)
                                    {
                                        LoadFolderAsSync(result.Entities.First());
                                    }
                                },
                                null);
                        }
                    }
                    else if (document != null)
                    {
                        //Check if the folder is not already open
                        foreach (var folderPage in from folderPage in FolderPages
                                                   from doc in folderPage.ListDocument
                                                   where doc.Identifier == document.Identifier
                                                   select folderPage)
                        {
                            folderPageAlreadyOpen = folderPage;
                            break;
                        }

                        if (folderPageAlreadyOpen == null)
                        {
                            FolderPage folderPage = new FolderPage(_searchHomeTab.Organization,
                                                                   _searchHomeTab.FolderType,
                                                                   document);

                            folderPage.LoadFolderDocument(null, true);
                            folderPage.DataHasChanged += FolderDataHasChanged;
                            folderPage.DocumentCopiedOrCuted += FolderPageDocumentCopiedOrPasted;

                            Tabs.Add(folderPage);

                            SelectedTab = folderPage;
                        }
                    }

                    if (folderPageAlreadyOpen != null)
                    {
                        MessageBoxChildWindow message = new MessageBoxChildWindow(
                            Resx.GetLabel(ResxSearchPage.FOLDER_IN_USE),
                            Resx.GetLabel(ResxSearchPage.FOLDER_IS_OPEN).Replace("\\n",
                                                                                                           Environment.
                                                                                                               NewLine),
                            MessageBoxButtons.Ok,
                            MessageBoxIcon.Warning);

                        message.Closed += (s, ev) => { SelectedTab = folderPageAlreadyOpen; };
                        message.ShowDialog();
                    }
                }
            }
            catch (Exception)
            {
                SplashScreenManager.Stop(this);
                throw;
            }
        }

        private void FolderDataHasChanged(object sender, EventArgs e)
        {
            IsDirty = true;
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        ///   Loads a folder
        /// </summary>
        /// <param name = "folder">The folder.</param>
        /// <param name = "organization">The organization.</param>
        /// <param name = "folderType">Type of the folder.</param>
        private void LoadFolderAsSync(Folder folder, Organization organization = null, FolderType folderType = null)
        {
            FolderPage folderPage;

            if (organization == null
                || folderType == null)
            {
                folderPage = new FolderPage(_searchHomeTab.Organization,
                                            _searchHomeTab.FolderType,
                                            folder);
            }
            else
            {
                folderPage = new FolderPage(organization, folderType, folder);
            }

            folderPage.DocumentCopiedOrCuted += FolderPageDocumentCopiedOrPasted;
            folderPage.DataHasChanged += FolderDataHasChanged;

            if (!Tabs.Contains(folderPage))
            {
                Tabs.Add(folderPage);
            }
            SelectedTab = folderPage;
            this.Cursor = Cursors.Arrow;
        }

        /// <summary>
        ///   Raised when a document in modification page is pasted or copied. We must reload each opened tabs folders to reload Paste menu
        /// </summary>
        /// <param name = "sender"></param>
        /// <param name = "e"></param>
        private void FolderPageDocumentCopiedOrPasted(object sender, PasteCopyEventArgs e)
        {
            foreach (var folderPage in FolderPages)
            {
                if (e.SourceFolder != null
                    && folderPage.CurrentFolder.Identifier == e.SourceFolder.Identifier)
                {
                    folderPage.LoadFolderDocument();
                }

                folderPage.ReloadPasteMenuVisibility();
            }
        }

        private void TabSelectionChanged()
        {
            //Disable all open notes when we return on the search tab
            if (Tabs.Count > 1)
            {
                foreach (FolderPage folderPage in FolderPages)
                {
                    if (folderPage.CommentChildWindow != null)
                    {
                        folderPage.CommentChildWindow.Visibility = Visibility.Collapsed;
                    }
                }
            }

            if (SelectedTab == _searchHomeTab)
            {
                if (IsDirty)
                {
                    _searchHomeTab.searchPanel.Search();
                    IsDirty = false;
                }
            }
            else
            {
                //Re-open the note when we return on the FolderPage
                FolderPage folderPage = SelectedTab as FolderPage;

                if (folderPage != null
                    && (folderPage.CommentChildWindow != null && (folderPage.CommentChildWindow.MustBeOpen)))
                {
                    folderPage.CommentChildWindow.Visibility = Visibility.Visible;
                }
            }
        }

        /// <summary>
        ///   Performs the consultation by URI.
        /// </summary>
        private void PerformConsultationByUri()
        {
            //Retrieve the folder consulted
            BusinessEntitiesDomainContext businessEntitiesDomainContext = new BusinessEntitiesDomainContext();
            var query = businessEntitiesDomainContext.GetFolderQuery(
                QueryByUriManager.SearchInstance.OrganizationId,
                QueryByUriManager.SearchInstance.FolderTypeId,
                QueryByUriManager.SearchInstance.FolderId,
                QueryByUriManager.SearchInstance.FolderIdDoc,
                null);

            businessEntitiesDomainContext.Load(
                query,
                PerformConsultationByUriCallback,
                null);
        }

        /// <summary>
        ///   Performs the consultation by URI callback.
        /// </summary>
        /// <param name = "result">The result.</param>
        private void PerformConsultationByUriCallback(LoadOperation<Folder> result)
        {
            if (result.Error == null
                && result.Entities != null
                && QueryByUriManager.SearchInstance != null)
            {
                /*
                 * Extract organization
                 */

                Organization organization = null;

                foreach (Group g in GlobalWebContext.CurrentUser.GroupList)
                {
                    foreach (Organization o in g.OrganizationList)
                    {
                        if (GlobalWebContext.OrganizationHaveFolderTypeRight(o, AppDisplayMode.Search)
                            && o.Identifier == QueryByUriManager.SearchInstance.OrganizationId)
                        {
                            organization = o;
                            break;
                        }
                    }
                }

                /*
                 * Extract FolderType
                 */

                FolderType folderType = null;

                FolderTypeComparer folderTypeComparer = new FolderTypeComparer();
                if (organization != null)
                {
                    foreach (FolderType f in organization.FolderTypesList)
                    {
                        if (
                            GlobalWebContext.CurrentUser.GroupList.Any(
                                userGroup => (userGroup.FolderTypeRigthList.Contains(f, folderTypeComparer))
                                             && ((userGroup.CanReorganize || userGroup.CanConsult))
                                             && f.Identifier == QueryByUriManager.SearchInstance.FolderTypeId))
                        {
                            folderType = f;
                        }
                    }
                }

                /*
                 * Extract Folder
                 */

                if (organization == null && folderType == null)
                {
                    MessageBoxChildWindow message = new MessageBoxChildWindow(
                        String.Empty,
                        "Vous ne disposez pas des droits d'accès au dossier!",
                        MessageBoxButtons.Ok,
                        MessageBoxIcon.Warning);

                    message.ShowDialog();
                }
                else
                {

                    Folder folder = result.Entities.SingleOrDefault();

                    if (folder != null)
                    {
                        QueryByUriManager.Finish();

                        var query = GlobalWebContext.BusinessEntitiesDomainContext.GetUsersByFolderIdQuery(folder.Iddoc);
                        GlobalWebContext.BusinessEntitiesDomainContext.Load(query, delegate(LoadOperation<User> operation)
                                                                                       {
                                                                                           List<User> users = new List<User>(operation.Entities);
                                                                                           if (users.Count > 0)
                                                                                           {
                                                                                               if (users.Any(p => p.UserId == GlobalWebContext.CurrentUser.UserId))
                                                                                               {
                                                                                                   LoadFolderAsSync(folder, organization, folderType);
                                                                                               }
                                                                                               else
                                                                                               {
                                                                                                   MessageBoxChildWindow message = new MessageBoxChildWindow(
                                                                                                       String.Empty,
                                                                                                       "Vous ne disposez pas des droits d'accès au dossier!",
                                                                                                       MessageBoxButtons.Ok,
                                                                                                       MessageBoxIcon.Warning);

                                                                                                   message.ShowDialog();
                                                                                               }
                                                                                           }
                                                                                           else
                                                                                           {
                                                                                               LoadFolderAsSync(folder, organization, folderType);
                                                                                           }

                                                                                       }, null);

                    }
                }
            }
        }

        private void CloseTabClick(object sender, RoutedEventArgs e)
        {
            FolderPage folderPage =
                ((RadTabItem)((RadButton)sender).GetParentByBaseType(typeof(RadTabItem), true)).Content as FolderPage;

            if (folderPage != null)
            {
                folderPage.DocumentCopiedOrCuted -= FolderPageDocumentCopiedOrPasted;
                folderPage.DataHasChanged -= FolderDataHasChanged;

                folderPage.Dispose();

                if (Tabs.Contains(folderPage))
                {
                    Tabs.Remove(folderPage);
                }
            }
        }

        private void TabTitleLoaded(object sender, RoutedEventArgs e)
        {
            object tabContent =
                ((RadTabItem)
                 ((TextBlock)sender).GetParentByBaseType(typeof(RadTabItem), true)).Content;

            string tabName;

            if (tabContent is FolderPage)
            {
                FolderPage folderPage = tabContent as FolderPage;

                tabName = Utils.GetFolderLabel(folderPage.CurrentFolder);

                tabName = String.IsNullOrWhiteSpace(tabName)
                              ? String.Format("{0} {1}",
                                              Resx.GetLabel(ResxSearchPage.FOLDER),
                                              _foldersCount++)
                              : String.Format("{0} : {1}",
                                              Resx.GetLabel(ResxSearchPage.FOLDER),
                                              tabName);
            }
            else
            {
                tabName = Resx.GetLabel(ResxSearchPage.MAINHEADERTAB);
            }

            ((TextBlock)sender).Text = tabName;

            if (tabContent is SearchHomeTab)
            {
                (((TextBlock)sender).Parent).FindChildByType<RadButton>().Visibility = Visibility.Collapsed;
            }
        }
    }
}